package main

import "fmt"

func main() {
	// 开辟一个切片，数据类型为int,3个元素，空间为5
	var numbers = make([]int, 3, 5)
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)
	fmt.Println("=========================================")
	// 向numbers切片追加一个元素1，len=4, [0,0,0,1], cap = 5
	numbers = append(numbers, 1)
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)
	fmt.Println("=========================================")

	// 向numbers切片追加一个元素2，len=5, [0,0,0,1,2], cap = 5
	numbers = append(numbers, 2)
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)
	fmt.Println("=========================================")

	// 向一个容量cap已经满的 slice 追加元素
	numbers = append(numbers, 3)
	// 按照扩容规则，新容量=5 * 2=10
	// 注意:在 Go 的切片扩容机制中,新容量通常不会严格等于 2 * 旧容量，而是会经过内存分配器的优化调整
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers)
	/*理论上，cap 应该从 5 变成 10（2 * oldcap）。
	实际上，Go 的内存分配器可能会选择一个更大的值（如 12），以减少未来扩容的开销。
	这不是 Bug，而是 Go 的优化策略，目的是减少频繁扩容带来的性能损耗。*/
	fmt.Println("=========================================")

	var numbers2 = make([]int, 3)
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2)
	numbers2 = append(numbers2, 1)
	fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2)
	// 原来的空间乘2，当空间大于1024时扩容1/4
}
